<script setup>
import axios from 'axios';
import { onMounted, ref, onUnmounted } from 'vue';
import moment from 'moment';

const dataList = ref([]);
const currentPage = ref(1);
const pageSize = ref(5);
const totalCount = ref(0);
const dialogFormVisible = ref(false);
const dialogFormTitle = ref('添加任务');
const formLabelWidth = '150px';
const form = ref({
  taskServer: '',
  targetType: '',
  modelFrame: '',
  media: '',
  mediaID: '',
  confidence: 0.5,
  pid: '',
  fps: '10',
});

const selectedModelType = ref('ALL');
const modelTypes = ref([{ key: 'all', value: 'ALL' }]);
const dialogFormModelTypes = ref([]);
const dialogFormTaskServers = ref([]);
const modelFrames = ref([]);
const mediaSource = ref([]);

onMounted(() => {
  loadModelTypeByCategory('modelType');
  loadDialogFormData();
  loadDataList();
  startStatusRefresh();
});

onUnmounted(() => {
  stopStatusRefresh();
});

const handleAppend = () => {
  dialogFormTitle.value = '添加任务';
  form.value = {
    taskServer: '',
    targetType: '',
    modelFrame: '',
    media: '',
    mediaID: '',
    confidence: 0.5,
    pid: '',
    fps: '10',
  };
  modelFrames.value = [];
  dialogFormVisible.value = true;
};

async function loadModelTypeByCategory(category) {
  try {
    const response = await axios.get(`/api/dictionary/${category}`);
    if (response.data.code === 0) {
      const newTypes = Object.entries(response.data.data).map(([key, value]) => ({ key, value }));
      if (category === 'modelType') {
        modelTypes.value = [{ key: 'all', value: 'ALL' }, ...newTypes];
      } else if (category === 'modelFrame') {
        modelFrames.value = newTypes;
      }
    } else {
      console.error('Failed to fetch category:', response.data.error);
    }
  } catch (error) {
    console.error('Error fetching category:', error);
  }
}

async function loadDialogFormData() {
  try {
    const response1 = await axios.get(`/api/dictionary/modelType`);
    const response2 = await axios.get(`/api/mediasource/url`);
    const response3 = await axios.get(`/api/dictionary/taskServer`);
    if (response1.data.code === 0) {
      const newTypes = Object.entries(response1.data.data).map(([key, value]) => ({ key, value }));
      dialogFormModelTypes.value = newTypes;
    } else {
      console.error('Failed to fetch dialogFormModelTypes:', response1.data.error);
    }

    if (response2.data.code === 0) {
      const newMediaSource = Object.entries(response2.data.data).map(([key, value]) => ({ key, value }));
      mediaSource.value = newMediaSource;
    } else {
      console.error('Failed to fetch MediaSource:', response2.data.error);
    }

    if (response3.data.code === 0) {
      const newTaskServers = Object.entries(response3.data.data).map(([key, value]) => ({ key, value }));
      dialogFormTaskServers.value = newTaskServers;
    } else {
      console.error('Failed to fetch dialogFormTaskServers:', response3.data.error);
    }
  } catch (error) {
    console.error('Error fetching DialogFormData:', error);
  }
}



const handleModelTypeChange = async () => {
  if (form.value.targetType) {
    await loadModelFramesByType(form.value.targetType);
  } else {
    modelFrames.value = [];
  }
};

const loadModelFramesByType = async (type) => {
  try {
    const response = await axios.get(`/api/dictionary/modelFrame`);
    if (response.data.code === 0) {
      const frames = Object.entries(response.data.data).map(([key, value]) => ({ key, value }));
      modelFrames.value = frames.filter(frame => frame.key === type);
    } else {
      console.error('Failed to fetch model frames:', response.data.error);
    }
  } catch (error) {
    console.error('Error fetching model frames:', error);
  }
};

const loadDataList = async () => {
  try {
    const params = {
      pageIndex: currentPage.value,
      pageSize: pageSize.value,
      targetType: selectedModelType.value === 'all' ? null : selectedModelType.value
    };

    const response = await axios.get('/api/task', { params });

    if (response.data.code === 0) {
      const tasks = response.data.data.tasks.map(task => ({
        ...task,
        status: 'Loading...'
      }));

      dataList.value = tasks;
      totalCount.value = response.data.data.total;
      updateTaskStatus();
    } else {
      console.error('Failed to fetch data:', response.data.error);
    }
  } catch (error) {
    console.error('Error fetching data:', error);
  }
};

const handleTypeChange = async () => {
  currentPage.value = 1;
  await loadDataList();
};

const formatTimestamp = timestamp => moment.utc(timestamp).format('YYYY-MM-DD HH:mm:ss.SSS');

const handleDelete = async (index, row) => {
  try {
    if (row.pid) {
      const stopResponse = await axios.post(`/api/task/${row.id}/stop`);
      if (!stopResponse.data.success) {
        console.error('Failed to stop task before deletion:', stopResponse.data.error);
      }
    }

    const deleteResponse = await axios.delete(`/api/task/${row.id}`);
    if (deleteResponse.data.success) {
      dataList.value.splice(index, 1);
      totalCount.value--;
      if (dataList.value.length < pageSize.value && currentPage.value * pageSize.value <= totalCount.value) {
        await loadDataList();
      }
    } else {
      console.error('Failed to delete task:', deleteResponse.data.error);
    }
  } catch (error) {
    console.error('Error deleting task:', error);
  }
};

const handleEdit = (index, row) => {
  form.value = { ...row };
  dialogFormTitle.value = '编辑任务';
  dialogFormVisible.value = true;
};

const handleSave = async () => {
  const method = dialogFormTitle.value === '添加任务' ? 'POST' : 'PUT';
  console.log(form.value)
  try {
    let response;
    if (method === 'POST') {
      response = await axios.post('/api/task', form.value);
    } else if (method === 'PUT') {
      response = await axios.put(`/api/task/${form.value.id}`, form.value);
    }

    if (response.data.success) {
      await loadDataList();
      dialogFormVisible.value = false;
    } else {
      console.error('Failed to save task:', response.data.error);
    }
  } catch (error) {
    console.error('Error saving task:', error);
  }
};

const handleStart = async (index, row) => {
  try {
    const response = await axios.post(`/api/task/${row.id}/start`);
    if (response.data.success) {
      dataList.value[index].pid = response.data.pid;
      updateTaskStatus();
    } else {
      console.error('Failed to start task:', response.data.error);
    }
  } catch (error) {
    console.error('Error starting task:', error);
  }
};

const handleStop = async (index, row) => {
  try {
    const response = await axios.post(`/api/task/${row.id}/stop`);
    if (response.data.success) {
      dataList.value[index].pid = null;
      updateTaskStatus();
    } else {
      console.error('Failed to stop task:', response.data.error);
    }
  } catch (error) {
    console.error('Error stopping task:', error);
  }
};

const handleCurrentChange = page => {
  currentPage.value = page;
  loadDataList();
};

let statusRefreshInterval;

const startStatusRefresh = () => {
  statusRefreshInterval = setInterval(updateTaskStatus, 3000);
};

const stopStatusRefresh = () => {
  clearInterval(statusRefreshInterval);
};

const updateTaskStatus = async () => {
  for (const task of dataList.value) {
    if (task.pid) {
      try {
        const response = await axios.get(`/api/task/status/${task.pid}`);
        if (response.data.code === 0) {
          task.status = response.data.status;
        } else {
          task.status = 'Unknown';
        }
      } catch (error) {
        task.status = 'Error';
        console.error('Error checking task status:', error);
      }
    } else {
      task.status = 'Down';
    }
  }
};

// 通过选择媒体资源 顺便设置媒体资源的ID
function handleMediaChange(value) {
  console.log('Selected value:', value);
  try {
    const selectedMedia = mediaSource.value.find(media => media.value === value);
    console.log('Selected media:', selectedMedia);
    if (selectedMedia) {
      form.value.mediaID = selectedMedia.key;
    } else {
      form.value.mediaID = '';
    }
  } catch (error) {
    console.error('Error in handleMediaChange:', error);
  }
  console.log("form.mediaID: ", form.value.mediaID)
}

</script>




<template>
  <div>
    <el-row style="margin: 5px; display: flex; justify-content: space-between;">
      <el-col :span="6">
        <el-select v-model="selectedModelType" placeholder="请选择搜索类型" @change="handleTypeChange">
          <el-option v-for="type in modelTypes" :key="type.key" :label="type.value" :value="type.key"></el-option>
        </el-select>
      </el-col>

      <el-col style="flex: 0 0 auto;">
        <el-button @click="handleAppend()">
          添加
        </el-button>
      </el-col>
    </el-row>
  </div>


  <div>
    <el-table class="tableClass" :data="dataList" style="width: 100%;" :default-expand-all="true" border
              :header-cell-style="{ background: '#eef1f6', color: '#606266' }" :row-style="{ height: '25px' }">
      <el-table-column type="index" width="45" :align="'center'"></el-table-column>
      <el-table-column prop="_id" label="ID" :show-overflow-tooltip="true" :align="'center'" :min-width="35" :max-width="44" width="auto"></el-table-column>
      <el-table-column prop="targetType" label="类型" :align="'center'" :min-width="30" :max-width="40" width="auto"></el-table-column>
      <el-table-column prop="modelFrame" label="模型框架" :show-overflow-tooltip="true" :align="'center'" :min-width="30" :max-width="40" width="auto"></el-table-column>
      <el-table-column prop="media" label="媒体资源" :show-overflow-tooltip="true" :align="'center'" :min-width="40" :max-width="50" width="auto"></el-table-column>
      <el-table-column prop="confidence" label="置信度" :align="'center'" :min-width="40" :max-width="50" width="auto">
        <template #default="{ row }">
          {{ row.confidence.toFixed(5) }}
        </template>
      </el-table-column>
      <el-table-column prop="fps" label="FPS" :align="'center'" :min-width="40" :max-width="50" width="auto"></el-table-column>
      <el-table-column prop="pid" label="PID" :align="'center'" :min-width="30" :max-width="40" width="auto"></el-table-column>
      <el-table-column prop="pid" label="状态" :show-overflow-tooltip="true" :align="'center'" :min-width="30" :max-width="40" width="auto">
        <template #default="scope">
          {{ scope.row.status }}
        </template>
      </el-table-column>

      <el-table-column prop="timestamp" label="时间" :show-overflow-tooltip="true" :align="'center'" :min-width="58" :max-width="60" width="auto">
        <template #default="scope">
          <span style="font-size: 10px;">
            {{ formatTimestamp(scope.row.timestamp) }}
          </span>
        </template>
      </el-table-column>

      <el-table-column label="操作" :show-overflow-tooltip="true" width="220" :align="'center'">
        <template #default="scope">
          <el-button size="small" type="primary" @click="handleEdit(scope.$index, scope.row)">
            <el-icon>
              <Edit />
            </el-icon>
          </el-button>

          <el-button size="small" type="success" @click="handleStart(scope.$index, scope.row)">
            <el-icon><VideoPlay /></el-icon>
          </el-button>

          <el-button size="small" type="info" @click="handleStop(scope.$index, scope.row)">
            <el-icon><VideoPause /></el-icon>
          </el-button>

          <el-popconfirm width="220" confirm-button-text="确定" @confirm="handleDelete(scope.$index, scope.row)"
                         cancel-button-text="取消" icon-color="#626AEF" title="确定删除此数据?">
            <template #reference>
              <el-button size="small" type="danger">
                <el-icon>
                  <Delete />
                </el-icon>
              </el-button>
            </template>
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>

    <el-pagination :page-size="pageSize" :current-page="currentPage" layout="->, total, prev,pager, next" :total="totalCount" @current-change="handleCurrentChange">
    </el-pagination>
  </div>

  <el-dialog v-model="dialogFormVisible" :title="dialogFormTitle" width="500">
    <el-form :model="form">
      <el-form-item label="推理地址" :label-width="formLabelWidth">
        <el-select v-model="form.taskServer" placeholder="请选择推理地址">
          <el-option v-for="type in dialogFormTaskServers" :key="type.key" :label="type.value" :value="type.value"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="类型" :label-width="formLabelWidth">
        <el-select v-model="form.targetType" placeholder="请选择类型" @change="handleModelTypeChange">
          <el-option v-for="type in dialogFormModelTypes" :key="type.key" :label="type.value" :value="type.key"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="模型框架" :label-width="formLabelWidth">
        <el-select v-model="form.modelFrame" placeholder="请选择模型框架" :disabled="modelFrames.length === 0">
          <el-option v-for="frame in modelFrames" :key="frame.key" :label="frame.value" :value="frame.value"></el-option>
        </el-select>
      </el-form-item>

      <el-form-item label="媒体资源" :label-width="formLabelWidth">
        <el-select v-model="form.media" placeholder="请选择媒体资源" @change="handleMediaChange">
          <el-option v-for="media in mediaSource" :key="media.key" :label="media.value" :value="media.value" style="width: 100%; max-width: 300px;"></el-option>
        </el-select>
      </el-form-item>

      <el-form-item label="置信度" :label-width="formLabelWidth">
        <el-input v-model="form.confidence" autocomplete="off" />
      </el-form-item>
      <el-form-item label="FPS" :label-width="formLabelWidth">
        <el-input v-model="form.fps" autocomplete="off" />
      </el-form-item>
<!--      <el-form-item label="PID" :label-width="formLabelWidth">-->
<!--        <el-input v-model="form.pid" autocomplete="off" disabled />-->
<!--      </el-form-item>-->
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取消</el-button>
        <el-button type="primary" @click="handleSave">确定</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<style scoped>
</style>
